#!/usr/bin/env python3
"""
微服务启动脚本
启动Web服务、调度器服务和执行器服务
"""

import os
import sys
import time
import signal
import subprocess
import threading
import platform
from datetime import datetime

# 设置时区（仅在Unix/Linux系统上可用）
if platform.system() != 'Windows':
    time.tzset()

class ServiceManager:
    """服务管理器"""
    
    def __init__(self):
        self.processes = {}
        self.running = True
        
    def start_service(self, name, script_path, port, env_vars=None):
        """启动服务"""
        try:
            # 设置环境变量
            env = os.environ.copy()
            if env_vars:
                env.update(env_vars)
            
            # 启动进程
            cmd = [sys.executable, script_path]
            if name != '监控服务':  # 监控服务不需要--host参数
                cmd.extend(['--host', '0.0.0.0'])  # 允许外部访问
            
            # 确保logs目录存在
            if not os.path.exists('logs'):
                os.mkdir('logs')
                
            # 创建日志文件名
            log_date = datetime.now().strftime('%Y-%m-%d')
            log_file = f"logs/{name.lower().replace(' ', '_')}_{log_date}.log"
            
            # 打开日志文件
            log_fd = open(log_file, 'a')
            
            # 启动进程，重定向标准输出和错误输出到日志文件
            process = subprocess.Popen(cmd, env=env, stdout=log_fd, stderr=log_fd)
            
            self.processes[name] = {
                'process': process,
                'port': port,
                'script_path': script_path,
                'log_fd': log_fd
            }
            
            print(f"✅ {name} 服务已启动 (PID: {process.pid}, 端口: {port})")
            
            # 等待服务启动
            time.sleep(3)
            
            return True
            
        except Exception as e:
            print(f"❌ 启动 {name} 服务失败: {str(e)}")
            return False
    
    def stop_service(self, name):
        """停止服务"""
        if name in self.processes:
            process_info = self.processes[name]
            process = process_info['process']
            
            try:
                process.terminate()
                process.wait(timeout=10)
                print(f"✅ {name} 服务已停止")
                
                # 关闭日志文件描述符
                if 'log_fd' in process_info and process_info['log_fd']:
                    try:
                        process_info['log_fd'].close()
                    except Exception as e:
                        print(f"⚠️ 关闭 {name} 服务日志文件失败: {str(e)}")
                    
            except subprocess.TimeoutExpired:
                process.kill()
                print(f"⚠️ {name} 服务被强制停止")
                
                # 关闭日志文件描述符
                if 'log_fd' in process_info and process_info['log_fd']:
                    try:
                        process_info['log_fd'].close()
                    except Exception as e:
                        print(f"⚠️ 关闭 {name} 服务日志文件失败: {str(e)}")
                    
            except Exception as e:
                print(f"❌ 停止 {name} 服务失败: {str(e)}")
            
            del self.processes[name]
    
    def stop_all_services(self):
        """停止所有服务"""
        print("\n🛑 正在停止所有服务...")
        for name in list(self.processes.keys()):
            self.stop_service(name)
    
    def check_service_status(self):
        """检查服务状态"""
        print("\n📊 服务状态:")
        print("=" * 50)
        
        for name, info in self.processes.items():
            process = info['process']
            port = info['port']
            
            if process.poll() is None:
                print(f"✅ {name}: 运行中 (PID: {process.pid}, 端口: {port})")
            else:
                print(f"❌ {name}: 已停止 (端口: {port})")
        
        print("=" * 50)
    
    def monitor_services(self):
        """监控服务状态"""
        while self.running:
            time.sleep(30)  # 每30秒检查一次
            
            # 检查是否有服务意外停止
            for name, info in list(self.processes.items()):
                process = info['process']
                if process.poll() is not None:
                    print(f"⚠️ {name} 服务意外停止，正在重启...")
                    self.stop_service(name)
                    self.start_service(name, info['script_path'], info['port'])
    
    def signal_handler(self, signum, frame):
        """信号处理器"""
        print(f"\n收到信号 {signum}，正在关闭服务...")
        self.running = False
        self.stop_all_services()
        sys.exit(0)

def main():
    """主函数"""
    print("🚀 启动定时任务管理平台微服务")
    print("=" * 50)
    print(f"启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print()
    
    # 创建服务管理器
    manager = ServiceManager()
    
    # 注册信号处理器
    signal.signal(signal.SIGINT, manager.signal_handler)
    signal.signal(signal.SIGTERM, manager.signal_handler)
    
    # 服务配置
    services = [
        {
            'name': 'Web服务',
            'script_path': 'services/web_service.py',
            'port': 8088,
            'env_vars': {
                'SCHEDULER_SERVICE_URL': 'http://localhost:5001',
                'EXECUTOR_SERVICE_URL': 'http://localhost:5002',
                'MONITOR_SERVICE_URL': 'http://localhost:5003'
            }
        },
        {
            'name': '调度器服务',
            'script_path': 'services/scheduler_service.py',
            'port': 5001,
            'env_vars': {
                'EXECUTOR_SERVICE_URL': 'http://localhost:5002'
            }
        },
        {
            'name': '执行器服务',
            'script_path': 'services/executor_service.py',
            'port': 5002,
            'env_vars': {}
        },
        {
            'name': '监控服务',
            'script_path': 'services/monitor_service.py',
            'port': 5003,
            'env_vars': {}
        }
    ]
    
    # 启动所有服务
    print("📋 启动服务列表:")
    for service in services:
        print(f"  - {service['name']}: 端口 {service['port']}")
    
    print()
    
    success_count = 0
    for service in services:
        if manager.start_service(
            service['name'], 
            service['script_path'], 
            service['port'],
            service['env_vars']
        ):
            success_count += 1
    
    if success_count == len(services):
        print(f"\n🎉 所有服务启动成功!")
        print(f"📱 Web界面: http://localhost:8088")
        print(f"🔧 调度器API: http://localhost:5001")
        print(f"⚡ 执行器API: http://localhost:5002")
        print(f"📊 监控API: http://localhost:5003")
        
        # 启动监控线程
        monitor_thread = threading.Thread(target=manager.monitor_services)
        monitor_thread.daemon = True
        monitor_thread.start()
        
        # 定期显示状态
        try:
            while manager.running:
                time.sleep(60)  # 每分钟显示一次状态
                manager.check_service_status()
        except KeyboardInterrupt:
            pass
        
    else:
        print(f"\n❌ 部分服务启动失败 ({success_count}/{len(services)})")
        manager.stop_all_services()
        sys.exit(1)

if __name__ == '__main__':
    main()